#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <cjson/cJSON.h>
#include <pthread.h>
#include <time.h>

#define PORT 8088
#define BUFFER_SIZE 1024
#define BOARD_SIZE 9

// 定义一个 9x9 的棋盘
int chessBoard[BOARD_SIZE][BOARD_SIZE] = {0};
pthread_mutex_t board_mutex = PTHREAD_MUTEX_INITIALIZER; // 保护棋盘的互斥锁

// 函数：在棋盘上放置棋子
int placePiece(int row, int col, int pieceNumber)
{
    if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE || pieceNumber < 0 || pieceNumber > 9)
    {
        return -1; // 无效的行、列或棋子编号
    }
    chessBoard[row][col] = pieceNumber;
    return 0; // 成功
}

// 函数：从棋盘上读取棋子
int getPiece(int row, int col)
{
    if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE)
    {
        return -1; // 无效的行或列
    }
    return chessBoard[row][col]; // 返回棋子编号，0 表示未填入棋子
}

// 函数：检查棋盘是否全部填充
int isBoardFullyFilled()
{
    pthread_mutex_lock(&board_mutex);
    for (int i = 0; i < BOARD_SIZE; i++)
    {
        for (int j = 0; j < BOARD_SIZE; j++)
        {
            if (chessBoard[i][j] == 0)
            {
                pthread_mutex_unlock(&board_mutex);
                printf("isBoardFullyFilled failed\n");
                return 0; // 未全部填充
            }
        }
    }
    pthread_mutex_unlock(&board_mutex);
    return 1; // 全部填充
}

// 函数：验证棋盘状态是否满足 answer 的要求
int verifyBoardWithAnswer(const char *answer)
{
    pthread_mutex_lock(&board_mutex);
    for (int i = 0; i < BOARD_SIZE; i++)
    {
        for (int j = 0; j < BOARD_SIZE; j++)
        {
            int piece = chessBoard[i][j];
            int answerPiece = answer[i * BOARD_SIZE + j] - '0';
            if (piece != answerPiece)
            {
                pthread_mutex_unlock(&board_mutex);
                printf("verifyBoardWithAnswer failed\n");
                return 0; // 不满足要求
            }
        }
    }
    pthread_mutex_unlock(&board_mutex);
    return 1; // 满足要求
}

// 线程函数：监听棋盘状态
void *listenBoardStatus(void *arg)
{
    while (1)
    {
        if (isBoardFullyFilled())
        {
            printf("Board is fully filled. Verifying...\n");
            const char *answer = (const char *)arg;
            if (verifyBoardWithAnswer(answer))
            {
                printf("Board is correctly filled according to the answer.\n");
            }
            else
            {
                printf("Board is filled, but does not match the answer.\n");
            }
            break;
        }
        sleep(1); // 稍作延迟
    }
    return NULL;
}

// 函数：使用 question 数据填充棋盘
int fillBoardWithQuestion(const char *question)
{
    if (strlen(question) != 81)
    {
        return -1; // question 长度不正确
    }

    int ret = 1;

    for (int i = 0; i < 81; i++)
    {
        int row = i / 9;
        int col = i % 9;
        int pieceNumber = question[i] - '0'; // 将字符转换为数字
        if (placePiece(row, col, pieceNumber) == -1)
        {
            ret = -1;
            return ret; // 放置棋子失败
        }
    }

    if (ret)
    {
        printf("placePiece is successful!\n");
    }
    else
    {
        printf("placePiece is failed!\n");
    }

    return 0; // 成功
}

// 函数：解析 JSON 数据为 C 字符串
char *parse_json_to_c_string(const char *json_data)
{
    cJSON *json = cJSON_Parse(json_data);
    if (json == NULL)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        return strdup("Invalid JSON data");
    }

    cJSON *problem = cJSON_GetObjectItemCaseSensitive(json, "problem");
    cJSON *question = cJSON_GetObjectItemCaseSensitive(json, "question");
    cJSON *answer = cJSON_GetObjectItemCaseSensitive(json, "answer");

    if (!cJSON_IsNumber(problem) || !cJSON_IsString(question) || !cJSON_IsString(answer))
    {
        cJSON_Delete(json);
        return strdup("Invalid JSON data: missing or invalid fields");
    }

    if (strlen(question->valuestring) != 81 || strlen(answer->valuestring) != 81)
    {
        cJSON_Delete(json);
        return strdup("Invalid JSON data: question or answer length is not 81");
    }

    // 校验 question 和 answer 是否只包含数字
    for (int i = 0; i < 81; i++)
    {
        if (question->valuestring[i] < '0' || question->valuestring[i] > '9' ||
            answer->valuestring[i] < '0' || answer->valuestring[i] > '9')
        {
            cJSON_Delete(json);
            return strdup("Invalid JSON data: question or answer contains non-digit characters");
        }
    }

    // 使用 question 数据填充棋盘
    if (fillBoardWithQuestion(question->valuestring) == -1)
    {
        cJSON_Delete(json);
        return strdup("Failed to place pieces on the board");
    }

    // 创建一个字符串来存储解析结果
    char *result = (char *)malloc(256 * sizeof(char));
    if (result == NULL)
    {
        cJSON_Delete(json);
        return strdup("Memory allocation failed");
    }

    snprintf(result, 256, "Problem: %d\nQuestion: %s\nAnswer: %s",
             problem->valueint, question->valuestring, answer->valuestring);

    cJSON_Delete(json);
    return result;
}

int main()
{
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE] = {0};
    char *response;

    // 创建 socket 文件描述符
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 设置 SO_REUSEADDR 选项
    int opt = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    // 绑定 socket 到指定的 IP 地址和端口
    address.sin_family = AF_INET;
    address.sin_port = htons(PORT);
    address.sin_addr.s_addr = INADDR_ANY;

    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
    {
        perror("bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server is listening on IP address: INADDR_ANY, port %d...\n", PORT);

    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)
    {
        perror("accept");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    printf("Client connected.\n");

    read(new_socket, buffer, BUFFER_SIZE);
    printf("Received data from client: %s\n", buffer);

    response = parse_json_to_c_string(buffer);
    if (response == NULL)
    {
        response = strdup("Invalid JSON data");
    }

    send(new_socket, response, strlen(response), 0);
    printf("Sent response to client: %s\n", response);

    free(response);

    // pthread_t thread, timer;

    // // 创建工作线程
    // pthread_create(&thread, NULL, listenBoardStatus, NULL);

    // // 创建定时器线程
    // pthread_create(&timer, NULL, timer_create, &thread);

    // // 等待工作线程结束
    // void* status;
    // pthread_join(thread, &status);

    // // 检查线程是否被取消
    // if (status == PTHREAD_CANCELED) {
    //     printf("Thread timed out and was cancelled.\n");
    // } else {
    //     printf("Thread completed successfully.\n");
    // }

    // // 等待定时器线程结束
    // pthread_join(timer, NULL);

    free(response);
    close(new_socket);
    close(server_fd);

    printf("Client disconnected.\n");

    return 0;
}